package gui;

import gui.abstracts.AbstractPanel;
import gui.abstracts.AbstractTable;
import gui.abstracts.ContainerAbstractObject;
import gui.containerDate.Item;
import gui.containerDate.Nodes;
import gui.panels.PanelButtons;
import gui.panels.PanelCardLayaut;
import gui.panels.PanelGroup;
import gui.panels.PanelStudent;
import gui.panels.PanelTree;
import gui.tables.TableGroup;
import gui.tables.TableStudent;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTree;

import javax.swing.event.TreeSelectionEvent;
import commandPatern.StoreCommands;
import commandPatern.SwitchComboBox;
import commandPatern.SwitchTree;

public class BaseFrame extends JFrame {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private PanelButtons panelButtons;
	private Toolbar toolbar;
	private String node = "Group";
	private SwitchTree swTree;
	private Item lastSelectItem = null;
	private SwitchComboBox swComboBox = null;

	public BaseFrame() throws InstantiationException, IllegalAccessException,
			ClassNotFoundException, SQLException {
		initGui();
	}

	private void initGui() throws InstantiationException,
			IllegalAccessException, ClassNotFoundException, SQLException {

		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle("Project");
		this.setSize(500, 300);
		this.setLocationRelativeTo(null);
		this.setLayout(new BorderLayout());
		this.add(PanelTree.getInstance(), BorderLayout.WEST);

		PanelTree.getInstance().getJTree().addTreeSelectionListener(new JTreeListner());
		panelButtons = new PanelButtons();
		this.add(panelButtons, BorderLayout.SOUTH);

		panelButtons.getButtonAdd().addActionListener(
				new ActionListnerAddButton());
		panelButtons.getButtonDel().addActionListener(
				new ActionListnerDellButton());
		panelButtons.getButtonOk().addActionListener(
				new ActionListnerOkButton());
		panelButtons.getButtonCancel().addActionListener(
				new ActionListnerCancelButton());
		panelButtons.getButtonEdit().addActionListener(
				new ActionListnerEditButton());
		panelButtons.getButtonOkEdit().addActionListener(
				new ActionListnerOkEditButton());
		panelButtons.getButtonCancelEdit().addActionListener(
				new ActionListnerCancelEditButton());

		this.add(PanelCardLayaut.getInstance());

		((PanelStudent) PanelCardLayaut.getInstance().getPanelStudent())
				.getComboBox().addActionListener(
						new ComboBoxActionListner("dsa"));

		this.setVisible(true);

		toolbar = new Toolbar();
		this.add(toolbar, BorderLayout.NORTH);
		toolbar.getUndoButton()
				.addActionListener(new ActionListnerUndoButton());
		toolbar.getUndoButton().setEnabled(
				StoreCommands.getInstance().canUndo());

		toolbar.getRendooButton().addActionListener(
				new ActionListnerRendooButton());
		toolbar.getRendooButton().setEnabled(
				StoreCommands.getInstance().canRendoo());

		initTableTreeData();
		setDefaultValues();
	}

	private void setDefaultValues() {
		ContainerAbstractObject.getInstance().setAbstractPanel(
				(AbstractPanel) PanelGroup.getInstance());
		ContainerAbstractObject.getInstance().setAbstractTable(
				(TableGroup) ((PanelGroup) PanelCardLayaut.getInstance()
						.getPanelGroup()).getTable());
		swTree = new SwitchTree(Nodes.GROUPS, ContainerAbstractObject
				.getInstance().getAbstractPanel());
	}

	private void initTableTreeData() throws InstantiationException,
			IllegalAccessException, ClassNotFoundException, SQLException {

		PanelGroup jTableGroup = (PanelGroup) PanelCardLayaut.getInstance()
				.getPanelGroup();
		jTableGroup.initTable();

		PanelStudent panelStudent = (PanelStudent) PanelCardLayaut
				.getInstance().getPanelStudent();

		panelStudent.initTable();
		
		PanelTree.getInstance().setLastSelect(Nodes.GROUPS);
	}

	private void checkToolbarButtons() {
		toolbar.getUndoButton().setEnabled(	StoreCommands.getInstance().canUndo());
		toolbar.getRendooButton().setEnabled(StoreCommands.getInstance().canRendoo());
	}

	private final class JTreeListner implements
			javax.swing.event.TreeSelectionListener {
		public void valueChanged(TreeSelectionEvent evt) {
			node = evt.getNewLeadSelectionPath().getLastPathComponent()
					.toString();
			if(! PanelTree.getInstance().isSelectable()){
				Nodes lastSelect = PanelTree.getInstance().getLastSelect();
				PanelTree.getInstance().getJTree().setSelectionRow(lastSelect.getId());

			}
			if (node.equals(Nodes.GROUPS.toString())) {
				
				StoreCommands.getInstance().clearStacks();
				
				ContainerAbstractObject.getInstance().setAbstractPanel(
						(AbstractPanel) PanelGroup.getInstance());
				ContainerAbstractObject.getInstance().setAbstractTable(
						(TableGroup) ((PanelGroup) PanelCardLayaut
								.getInstance().getPanelGroup()).getTable());

				((CardLayout) PanelCardLayaut.getInstance().getLayout()).show(PanelCardLayaut.getInstance(), Nodes.GROUPS.toString());
				PanelTree.getInstance().setLastSelect(Nodes.GROUPS);
			} else if (node.equals(Nodes.STUDENTS.toString())) {
				
				StoreCommands.getInstance().clearStacks();
				
				ContainerAbstractObject.getInstance().setAbstractPanel(
						(AbstractPanel) PanelCardLayaut.getInstance()
								.getPanelStudent());
				ContainerAbstractObject.getInstance().setAbstractTable(
						(TableStudent) ((PanelStudent) PanelCardLayaut
								.getInstance().getPanelStudent()).getTable());

				((CardLayout) PanelCardLayaut.getInstance().getLayout()).show(
						PanelCardLayaut.getInstance(),
						Nodes.STUDENTS.toString());
				
				PanelTree.getInstance().setLastSelect(Nodes.STUDENTS);
			}
			checkToolbarButtons();
		}
	}

	private void cancelInsert() {

		ContainerAbstractObject.getInstance().getAbstractPanel().cancelInsert();

		panelButtons.getButtonOk().setVisible(false);
		panelButtons.getButtonCancel().setVisible(false);

		panelButtons.getButtonAdd().setEnabled(true);
		panelButtons.getButtonDel().setEnabled(true);

	}

	private void insertObjectInDb() throws InstantiationException,
			IllegalAccessException, ClassNotFoundException, SQLException {

		ContainerAbstractObject.getInstance().getAbstractPanel()
				.insertObjectInDb();

		PanelTree.getInstance().setSelectable(true);
		
		panelButtons.getButtonOk().setVisible(false);
		panelButtons.getButtonCancel().setVisible(false);

		panelButtons.getButtonAdd().setEnabled(true);
		panelButtons.getButtonDel().setEnabled(true);

		checkToolbarButtons();

	}

	public void insertRowInTable() {

		ContainerAbstractObject.getInstance().getAbstractTable().insertRowInTable();

		panelButtons.getButtonOk().setVisible(true);
		panelButtons.getButtonCancel().setVisible(true);

		panelButtons.getButtonAdd().setEnabled(false);
		panelButtons.getButtonDel().setEnabled(false);
	}

	public void removeRowFromTable() throws InstantiationException,
			IllegalAccessException, ClassNotFoundException, SQLException {

		ContainerAbstractObject.getInstance().getAbstractPanel()
				.removeRowFromTable();
		PanelTree.getInstance().setSelectable(true);
		checkToolbarButtons();
	}

	public void edit() throws InstantiationException, IllegalAccessException,
			ClassNotFoundException, SQLException {

		panelButtons.getButtonCancelEdit().setVisible(true);
		panelButtons.getButtonOkEdit().setVisible(true);
		panelButtons.getButtonAdd().setEnabled(false);
		panelButtons.getButtonDel().setEnabled(false);
		ContainerAbstractObject.getInstance().getAbstractPanel().edit();

	}

	public void SubmitEdit() throws InstantiationException,
			IllegalAccessException, ClassNotFoundException, SQLException {
		ContainerAbstractObject.getInstance().getAbstractPanel().SubmitEdit();
		panelButtons.getButtonCancelEdit().setVisible(false);
		panelButtons.getButtonOkEdit().setVisible(false);
		panelButtons.getButtonAdd().setEnabled(true);
		panelButtons.getButtonDel().setEnabled(true);

		checkToolbarButtons();
	}

	public void cancelEdit() throws InstantiationException,
			IllegalAccessException, ClassNotFoundException, SQLException {
		ContainerAbstractObject.getInstance().getAbstractPanel().cancelEdit();
		panelButtons.getButtonCancelEdit().setVisible(false);
		panelButtons.getButtonOkEdit().setVisible(false);
		panelButtons.getButtonAdd().setEnabled(true);
		panelButtons.getButtonDel().setEnabled(true);
		
		
	}

	private void undo() throws InstantiationException, IllegalAccessException,
			ClassNotFoundException, SQLException {
		StoreCommands.getInstance().undo();

		checkToolbarButtons();
	}

	private void rendo() throws InstantiationException, IllegalAccessException,
			ClassNotFoundException, SQLException {
		StoreCommands.getInstance().rendo();

		checkToolbarButtons();
	}

	private final class ComboBoxActionListner implements ActionListener {
		public ComboBoxActionListner(String s) {

		}

		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				System.out.println("source " + e.getSource());
				System.out.println("Actioncommand " + e.getActionCommand());
				System.out.println("modifiers" + e.getModifiers());
				System.out.println("param string       " + e.paramString());
				System.out.println("hash code             " + e.hashCode());
				// System.out.println("hash code             "+e.);

				JComboBox comboBox = (JComboBox) e.getSource();

				Item item = (Item) comboBox.getSelectedItem();

				StoreCommands.getInstance().clearStacks();
				checkToolbarButtons();
				PanelStudent.getInstance().setStudentTable(item);

			} catch (Exception e1) {
				new RuntimeException(e1);
			}
		}
	}

	private final class ActionListnerDellButton implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {

			try {
				removeRowFromTable();
			} catch (Exception e1) {
				new RuntimeException(e1);
			}

		}

	}

	private final class ActionListnerCancelButton implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			PanelTree.getInstance().setSelectable(true);
			cancelInsert();
		}

	}

	private final class ActionListnerCancelEditButton implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {

			try {
				//System.out.println("cancelEdit");
				cancelEdit();
				PanelTree.getInstance().setSelectable(true);
			} catch (Exception e1) {
				new RuntimeException(e1);
			}

		}

	}

	private final class ActionListnerOkButton implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {

			try {
				insertObjectInDb();
			} catch (Exception e1) {
				new RuntimeException(e1);
			}

		}

	}

	private final class ActionListnerEditButton implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {

			try {
				PanelTree.getInstance().setSelectable(false);
				edit();
			} catch (Exception e1) {
				new RuntimeException(e1);
			}
		}

	}

	private final class ActionListnerOkEditButton implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				SubmitEdit();
				PanelTree.getInstance().setSelectable(true);
			} catch (Exception e1) {
				new RuntimeException(e1);
			}
		}
	}

	private final class ActionListnerAddButton implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			PanelTree.getInstance().setSelectable(false);

			insertRowInTable();
		}
	}

	private final class ActionListnerUndoButton implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				undo();
			} catch (Exception e1) {
				new RuntimeException(e1);
			}
		}
	}

	private final class ActionListnerRendooButton implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {

			try {
				rendo();
			} catch (Exception e1) {
				new RuntimeException(e1);
			}
		}
	}

}
